home *** CD-ROM | disk | FTP | other *** search
- #include <graphics libraries.h>
- #include <graphics toolbox.h>
- #include "TileConstants.h"
- #include "SymmetryUtils.h"
-
- //-------------------------------------------------------------
- // Routine to create the various symmetry operation shapes
-
- gxShape MakeOpShape(long theType)
- {
- // Cap stuff
- gxCapRecord myCapRec;
- gxDashRecord theDashRecord;
- gxShape theShape = nil, tempShape, otherTempShape;
- long genericLine[] = { 0, 0, 0, kStartingGridSize };
- gxRectangle roundCapBounds = {-ff(1), -ff(1), ff(1), ff(1)},
- dashRect = {0, -fl(.5), ff(10), fl(.5)},
- ovalRect = {-ff(1), -ff(2), ff(1), ff(2)};
- gxPoint aPoint = {0, 0};
- long arrowGon[] = { 4,
- ff(5), 0,
- 0, -ff(2),
- 0, 0,
- 0, ff(2) };
-
- switch(theType)
- {
- case transOp: // translation shape, arrow with starting dot
- theShape = GXNewLine((gxLine *)genericLine);
- GXSetShapePen(theShape, ff(3));
-
- // arrow head and dot are line caps
- tempShape = NewPolygon((gxPolygon *) arrowGon);
- otherTempShape = NewArc(&roundCapBounds, ff(0), ff(360), true);
- myCapRec.startCap = otherTempShape;
- myCapRec.endCap = tempShape;
- myCapRec.attributes = gxNoAttributes;
- GXSetShapeCap(theShape, &myCapRec);
- SetShapeCommonColor(theShape, kTranslateColor);
- GXDisposeShape(tempShape);
- GXDisposeShape(otherTempShape);
- break;
-
- case reflOp: // reflection, a simple line
- theShape = GXNewLine((gxLine *)genericLine);
- GXSetShapePen(theShape, ff(3));
- GXScaleShape(theShape, 0, ff(2), 0, 0);
- GXMoveShape(theShape, 0, -(kStartingGridSize / 2) );
- SetShapeCommonColor(theShape, kMirrorColor);
- break;
-
- case glideOp: // glide reflection, a dashed line with arrow head
- theShape = GXNewLine((gxLine *)genericLine);
- GXSetShapePen(theShape, ff(3));
- // GXMoveShape(theShape, 0, -(kStartingGridSize / 2) );
-
- // Add the cap
- tempShape = NewPolygon((gxPolygon *) arrowGon);
- myCapRec.startCap = nil;
- myCapRec.endCap = tempShape;
- myCapRec.attributes = gxNoAttributes;
- GXSetShapeCap(theShape, &myCapRec);
- GXDisposeShape(tempShape);
-
- /* // Add the dash
- tempShape = GXNewRectangle(&dashRect);
- theDashRecord.attributes = gxClipDash; // + gxAutoAdvanceDash;
- theDashRecord.dash = tempShape;
- theDashRecord.advance = ff(16);
- theDashRecord.phase = 0;
- theDashRecord.scale = ff(1);
- GXSetShapeDash(theShape, &theDashRecord);
- GXDisposeShape(tempShape);
- */
- // Set color
- SetShapeCommonColor(theShape, kGlideColor);
- break;
-
- case roto2Op: // center of 180 degree rotation
- theShape = GXNewPoint(&aPoint);
- GXSetShapePen(theShape, ff(5));
-
- // oval is a line cap
- tempShape = NewOval(&ovalRect);
- myCapRec.startCap = tempShape;
- myCapRec.endCap = nil;
- myCapRec.attributes = gxNoAttributes;
- GXSetShapeCap(theShape, &myCapRec);
- SetShapeCommonColor(theShape, kRotoColor);
- GXDisposeShape(tempShape);
- break;
- }
- return theShape;
- }
-
-
- // Moves the glide shape as appropriate. Gnarly.
- void DragGlideShape(gxShape dragShape, gxPoint *newPt, gxPoint *oldPt,
- gxPoint *anchor, long constraint, Boolean arrowHit)
- {
- fixed xd = newPt->x - anchor->x,
- lxd = labs(newPt->x - anchor->x);
- fixed yd = newPt->y - anchor->y,
- lyd = labs(newPt->y - anchor->y);
- fixed theLine[4];
- //fixed slope;
-
- GXGetLine(dragShape, (gxLine *)theLine);
- //slope = FixDiv(theLine[3] - theLine[1], theLine[2] - theLine[0]);
-
- // Set up to move shape
- switch(constraint)
- {
- case constrainH: // Assumes a vertical glide line, pointing down
- // If it's in bounds, just set the x coords to the new point's
- if( lxd > kMinDistance && lxd < kMaxDistance )
- {
- theLine[0] = theLine[2] = newPt->x;
- }
- else if( lxd > kMaxDistance )
- {
- // Set to the max
- theLine[0] = theLine[2] =
- anchor->x + ( (xd < 0) ? -kMaxDistance : kMaxDistance);
- }
- else if( lxd < kMinDistance )
- {
- // Set to the min
- theLine[0] = theLine[2] =
- anchor->x + ( (xd < 0) ? -kMinDistance : kMinDistance);
- }
-
- // Set the length if arrow is hit
- if(arrowHit)
- {
- // If it's in bounds, just set the y coord to the new point's
- if( yd > kMinDistance && yd < kMaxDistance )
- {
- theLine[3] = newPt->y;
- }
- else if( yd > kMaxDistance )
- {
- // Set to the max
- theLine[3] = anchor->y + kMaxDistance;
- }
- else if( yd < kMinDistance )
- {
- // Set to the min
- theLine[3] = anchor->y + kMinDistance;
- }
- }
- break;
-
- default:
- break;
- }
- GXSetLine(dragShape, (gxLine *)theLine);
- }
-
- // Moves the line shape as appropriate.
- void DragLineShape(gxShape dragShape, gxPoint *newPt, gxPoint *oldPt,
- gxPoint *anchor, long constraint)
- {
- fixed xd = newPt->x - anchor->x,
- lxd = labs(newPt->x - anchor->x);
- fixed yd = newPt->y - anchor->y,
- lyd = labs(newPt->y - anchor->y);
- fixed theLine[4];
- //fixed slope;
-
- GXGetLine(dragShape, (gxLine *)theLine);
- //slope = FixDiv(theLine[3] - theLine[1], theLine[2] - theLine[0]);
-
- // Set up to move shape
- switch(constraint)
- {
- case constrainH:
- // If it's in bounds, just set the x coords to the new point's
- if( lxd > kMinDistance && lxd < kMaxDistance )
- {
- theLine[0] = theLine[2] = newPt->x;
- }
- else if( lxd > kMaxDistance )
- {
- // Set to the max
- theLine[0] = theLine[2] =
- anchor->x + ( (xd < 0) ? -kMaxDistance : kMaxDistance);
- }
- else if( lxd < kMinDistance )
- {
- // Set to the min
- theLine[0] = theLine[2] =
- anchor->x + ( (xd < 0) ? -kMinDistance : kMinDistance);
- }
- break;
-
- case constrainV:
- // If it's in bounds, just set the y coords to the new point's
- if( lyd > kMinDistance && lyd < kMaxDistance )
- {
- theLine[0] = theLine[2] = newPt->y;
- }
- else if( lyd > kMaxDistance )
- {
- // Set to the max
- theLine[0] = theLine[2] =
- anchor->y + ( (yd < 0) ? -kMaxDistance : kMaxDistance);
- }
- else if( lyd < kMinDistance )
- {
- // Set to the min
- theLine[0] = theLine[2] =
- anchor->y + ( (yd < 0) ? -kMinDistance : kMinDistance);
- }
- break;
- default:
- break;
- }
- GXSetLine(dragShape, (gxLine *)theLine);
- }
-